package com.baidu.sggc.core.interceptor;

import com.baidu.sggc.entity.LoginUserInfo;
import com.baidu.sggc.entity.UserContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Optional;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Value("${IDaas.idaasProjectUrl}")
    private String idaasProjectUrl;

    @Value("${IDaas.loginUrl}")
    private String loginUrl;

    @Value("${fe.port}")
    private String fePort;

    @Value("${fe.contextPath}")
    private String feContextPath;

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Optional<String> sessionIdOpt = extractSessionId(request.getCookies());

//        if (!sessionIdOpt.isPresent()) {
//            log.warn("未授权: idaas-sessionid Cookie 不存在, uri={}", request.getRequestURI());
//            sendJsonRedirect(request, response);
//            return false;
//        }
//
//        JsonNode userNode = verifySessionAndGetUser(sessionIdOpt.get());
//        if (userNode == null || userNode.path("id").asText().isEmpty()) {
//            log.warn("未授权: 用户信息无效, sessionId={}, uri={}", sessionIdOpt.get(), request.getRequestURI());
//            sendJsonRedirect(request, response);
//            return false;
//        }
//
//        String userId = userNode.path("id").asText();
//        String userName = userNode.path("name").asText();
//        UserContext.setUser(new LoginUserInfo(userId, userName));
//        log.info("认证通过, userId={}", userId);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserContext.clear();
    }

    /**
     * 提取 idaas-sessionid Cookie
     */
    private Optional<String> extractSessionId(Cookie[] cookies) {
        if (cookies == null) {
            return Optional.empty();
        }

        return Arrays.stream(cookies)
                .filter(cookie -> "idaas-sessionid".equalsIgnoreCase(cookie.getName()))
                .map(Cookie::getValue)
                .filter(StringUtils::hasText)
                .findFirst();
    }

    /**
     * 验证会话，获取用户信息
     */
    private JsonNode verifySessionAndGetUser(String sessionId) {
        String url = idaasProjectUrl + "/idgate/v1/user/authSession";
        Map<String, Object> body = new HashMap<>();
        body.put("sessionId", sessionId);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Accept", "application/json");

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
            String responseBody = response.getBody();
            // 生产环境建议不打印 responseBody，除非出错时 trace
            JsonNode json = new ObjectMapper().readTree(responseBody);
            return json.path("result").path("user");
        } catch (Exception e) {
            log.error("验证 session 失败, sessionId={}", sessionId, e);
            return null;
        }
    }

    /**
     * Ajax 兼容的登录重定向响应
     */
    private boolean sendJsonRedirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String scheme = request.getScheme();
        String serverName = request.getServerName();
        String uri = request.getRequestURI();
        String query = request.getQueryString();

        String currentUrl = scheme + "://" + serverName +
                fePort + feContextPath +
                uri +
                (StringUtils.hasText(query) ? "?" + query : "");

        String redirectParam = URLEncoder.encode(currentUrl, "UTF-8");
        String joinChar = loginUrl.contains("?") ? "&" : "?";
        String loginRedirectUrl = loginUrl + joinChar + "redirect=" + redirectParam;

        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");

        String json = String.format(
                "{\"code\":401,\"msg\":\"未登录或登录失效\",\"redirect\":\"%s\"}",
                loginRedirectUrl
        );
        // log.debug("返回 JSON：{}", json); // 如无必要，注释掉
        response.getWriter().write(json);
        return false;
    }


}